﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;

namespace Logger
{
    public class Logger : IPlugin.IPlugin
    {
        #region InfoPlugin

        public string[] Authors
        {
            get
            {
                return new string[] { "Manuel Fernandez" };
            }
        }

        public string Name
        {
            get
            {
                return "Status";
            }
        }

        public string Description
        {
            get
            {
                return "Logs input requests";
            }
        }

        public IPlugin.PluginRing Ring
        {
            get
            {
                return IPlugin.PluginRing.Ring0;
            }
        }
        #endregion

        public Model.Elements.HttpPacket Start(Model.Elements.HttpPacket packet)
        {
            System.Threading.ReaderWriterLockSlim writeLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

            if (packet is Model.Elements.HttpRequestPacket)
            {
                Model.Elements.HttpRequestPacket request = packet as Model.Elements.HttpRequestPacket;

                if (!Directory.Exists(Configuration.Configuration.logsPath))
                    Directory.CreateDirectory(Configuration.Configuration.logsPath);

                /*
                 * <request date="" ip="" method="" uri="" version="">
                 *      <headers>
                 *          <header name="" value=""/>
                 *          ...
                 *      </headers>
                 *      
                 *      <data content="">
                 * </request>
                 */

                string logFile = string.Format(@"{0}\log.xml", Configuration.Configuration.logsPath);

                StringBuilder xmlSb = new StringBuilder();
                xmlSb.Append(string.Format("<request date='{0}' ip='{1}' method='{2}' uri='{3}' version='{4}'>\r\n", string.Format("{0} {1}", 
                                            DateTime.Now.ToShortDateString(), DateTime.Now.ToShortTimeString()),
                                            request.clientIp,
                                            request.method.Replace("\\","\\\\").Replace("'",@"\'"),
                                            request.uri.Replace("\\", "\\\\").Replace("'", @"\'"),
                                            request.version.Replace("\\","\\\\").Replace("'",@"\'")
                            ));

                xmlSb.Append("  <headers>\r\n");
                foreach (Model.Elements.HttpHeader header in request.lstHeaders)
                {
                    xmlSb.Append(string.Format("    <header name='{0}' value='{1}' />\r\n",
                                            header.name.Replace("\\", "\\\\").Replace("'", @"\'"),
                                            header.value.Replace("\\","\\\\").Replace("'",@"\'")
                                ));
                }                
                xmlSb.Append("  </headers>\r\n");

                if (request.data != null)
                    xmlSb.Append(string.Format("  <data content='{0}' />\r\n", ASCIIEncoding.ASCII.GetString(request.data)));

                xmlSb.Append("</request>\r\n");
                writeLock.EnterWriteLock();
                try
                {
                    File.AppendAllText(logFile, xmlSb.ToString());
                }
                catch
                {
                    Console.WriteLine("Error writing log file. WriteLock");
                }
                finally
                {
                    writeLock.EnterWriteLock();
                }
            }

            return packet;
        }
    }
}
